package tf.mcs.imp.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tf.mcs.imp.config.EasyExcelListener;
import tf.mcs.imp.config.ExcelListener;
import tf.mcs.imp.entity.*;
import tf.mcs.imp.service.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author ：Zhiwei Wang
 * @version ：1.0$
 * @ClassName ：ImpController
 * @description ：Excel导入接口
 * @date ：2022/11/8 19:30
 * @history ：
 */
@RestController
public class ImpController {
    Logger log = LoggerFactory.getLogger(ImpController.class);
    private static Integer before = 0;
    private static Integer now = 0;
    @Autowired
    private ICnIljsChnlService chnlService;
    @Autowired
    private ICnIljsParserdefService parserdefService;
    @Autowired
    ICnIljsSvrcatalogService svrcatalogService;
    @Autowired
    ICnIljsSvrdefService svrdefService;
    @Autowired
    ImpService impService;

    @GetMapping("/download")
    @ApiOperation(value = "模板下载")
    public void downloadImportFileSubject(HttpServletResponse response) throws IOException {
        //方式1： 流的方式
        String fileName = "同方软银零售业务内联站点接口导入模板.xlsx";
        ClassPathResource classPathResource = new ClassPathResource(fileName);
        InputStream inputStream = classPathResource.getInputStream();
        response.reset();
        response.setContentType("application/octet-stream");
        response.setHeader("content-type", "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName,"utf8"));
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] b = new byte[1024];
        int len;
//从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
        while ((len = inputStream.read(b)) > 0) {
            outputStream.write(b, 0, len);
        }
        inputStream.close();
    }

    @ApiOperation(value = "导入xlsx文件")
    @PostMapping(value = "update")
    @Transactional(rollbackFor = Exception.class)
    public String update(
            @ApiParam(value = "格式必须是 xlsx", required = true) MultipartFile file) throws IOException {
        // 1. 读取excel内容
        try {
            EasyExcelListener easyExcelListener = new EasyExcelListener();
            InputStream inputStream = file.getInputStream();
            ExcelReaderBuilder read = EasyExcelFactory.read(file.getInputStream(), easyExcelListener);
            ExcelReader excelReader = read.build();
            // 2.获取各个sheet页信息
            List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
            // 3. 将各个Shhet页表格内容存于map
            Map<String, List<LinkedHashMap>> sheetInfos = new HashMap<>(sheets.size());
            for (ReadSheet sheet : sheets) {
                String sheetName = sheet.getSheetName();
                excelReader.read(sheet);
                sheetInfos.put(sheetName, easyExcelListener.getListMap());
            }
            //拿到附件地址，将文件存储业务使用
//        String upload = FileUploadUtils.upload(file);
            // 调用setCompetitiongroupReport()将文档内容进行读取，
            // get(0)是默认读取"通信渠道"sheet页
            List<CnIljsChnl> cnIljsChnls = impService.getCnIljsChnl(sheetInfos.get("通信渠道"));
            for (CnIljsChnl cnIljsChnl : cnIljsChnls) {
                //删除数据
                QueryWrapper<CnIljsChnl> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(CnIljsChnl::getChnlcode, cnIljsChnl.getChnlcode());
                chnlService.remove(queryWrapper);
                chnlService.save(cnIljsChnl);

                // 读取"接口列表"
                //根据chnlcode获取并处理公共报文
                List<CnIljsSvrcatalog> svrcatalogs = impService.getCnIljsCatalogs(sheetInfos.get("接口列表"));
                for (CnIljsSvrcatalog catalog : svrcatalogs) {
                    QueryWrapper<CnIljsSvrcatalog> qw = new QueryWrapper<>();
                    qw.lambda().eq(CnIljsSvrcatalog::getSvrcode, catalog.getSvrcode());
                    svrcatalogService.remove(qw);
                }
                svrcatalogService.saveBatch(svrcatalogs);
                log.info(svrcatalogs.toString());

                List<CnIljsParserdef> parserdefs = impService.getParserdefs(sheetInfos.get("接口列表"));
                for (CnIljsParserdef parserdef : parserdefs) {
                    QueryWrapper<CnIljsParserdef> qw = new QueryWrapper<>();
                    qw.lambda().eq(CnIljsParserdef::getSvrcode, parserdef.getSvrcode());
                    parserdefService.remove(qw);
                }
                parserdefService.saveBatch(parserdefs);

                //读取“具体接口”
                List<CnIljsSvrdef> cnIljsSvrdefs = impService.getCnIljsSvrdefs(sheetInfos, svrcatalogs);
                cnIljsSvrdefs = impService.getDataFormat(cnIljsSvrdefs);
                for (CnIljsSvrdef svrdef : cnIljsSvrdefs) {
                    QueryWrapper<CnIljsSvrdef> qw = new QueryWrapper<>();
                    qw.lambda().eq(CnIljsSvrdef::getSvrcode, svrdef.getSvrcode());
                    svrdefService.remove(qw);
                }
                svrdefService.saveBatch(cnIljsSvrdefs);
                log.info(cnIljsSvrdefs.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "导入失败：" + e.getMessage();
        }
        return "导入成功！";
    }
}
